package juejin;

import java.util.LinkedList;
import java.util.Queue;

public class MyBlockQueue<T> {

    private final Queue<T> queue;
    private final int capacity;

    public MyBlockQueue(int capacity) {
        this.queue = new LinkedList<>();
        this.capacity = capacity;
    }

    // 生产者方法，添加元素到队列
    public synchronized void put(T element) throws InterruptedException {
        while (queue.size() == capacity) {
            wait(); // 队列已满，等待消费者消费
        }
        queue.add(element);
        notifyAll(); // 唤醒等待的消费者
        System.out.println("Produced: " + element);
    }

    // 消费者方法，从队列中取出元素
    public synchronized T take() throws InterruptedException {
        while (queue.isEmpty()) {
            wait(); // 队列为空，等待生产者生产
        }
        T element = queue.poll();
        notifyAll(); // 唤醒等待的生产者
        System.out.println("Consumed: " + element);
        return element;
    }

    public static void main(String[] args) throws InterruptedException {
        MyBlockQueue<Integer> blockQueue = new MyBlockQueue<>(5);
        Thread producer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    blockQueue.put(i);
                    Thread.sleep(100); // 模拟生产时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            for (int i = 0; i < 20; i++) {
                try {
                    blockQueue.take();
                    Thread.sleep(150); // 模拟消费时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        });

        producer.start();
        consumer.start();
    }
}
